package cn.bugstack.domain.trade.service.settlement;

import cn.bugstack.domain.trade.adapter.ITradeRepository;
import cn.bugstack.domain.trade.adapter.port.ITradePort;
import cn.bugstack.domain.trade.model.aggregate.GroupBuyTeamSettlementAggregate;
import cn.bugstack.domain.trade.model.entity.*;
import cn.bugstack.domain.trade.service.ITradeSettlementOrderService;
import cn.bugstack.domain.trade.service.settlement.factory.TradeSettlementRuleFilterFactory;
import cn.bugstack.types.design.framework.link.model2.BusinessLinkedList;
import cn.bugstack.types.enums.NotifyTaskHTTPEnumVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 代码的路
 * @Date: 2025/3/4 10:19
 * @Param:
 * @Return:
 * @Description:
 **/
@Service
@Slf4j
public class TradeSettlementOrderService implements ITradeSettlementOrderService {


    @Resource
    private ITradeRepository repository;

    @Resource
    private BusinessLinkedList<TradeSettlementRuleCommandEntity,
            TradeSettlementRuleFilterFactory.DynamicContext, TradeSettlementRuleFilterBackEntity> tradeSettlementRuleFilter;

    @Resource
    private ITradePort tradePort;

    @Override
    public TradePaySettlementEntity settlementMarketPayOrder(TradePaySuccessEntity tradePaySuccessEntity) {

        //1.查询订单信息
        TradeSettlementRuleCommandEntity commandEntity = new TradeSettlementRuleCommandEntity();
        BeanUtils.copyProperties(tradePaySuccessEntity, commandEntity);
        TradeSettlementRuleFilterBackEntity apply = tradeSettlementRuleFilter.apply(commandEntity, new TradeSettlementRuleFilterFactory.DynamicContext());

        //2.查询拼团信息
        GroupBuyTeamEntity groupBuyTeamEntity = new GroupBuyTeamEntity();
        BeanUtils.copyProperties(apply, groupBuyTeamEntity);


        //3.构建组团信息
        GroupBuyTeamSettlementAggregate groupBuyTeamSettlementAggregate = GroupBuyTeamSettlementAggregate.builder()
                .userEntity(UserEntity.builder().userId(tradePaySuccessEntity.getUserId()).build())
                .groupBuyTeamEntity(groupBuyTeamEntity)
                .tradePaySuccessEntity(tradePaySuccessEntity)
                .build();


        //4。拼团交易结算
        repository.settlementMarketPayOrder(groupBuyTeamSettlementAggregate);

        //5.组队回调处理 -处理失败也会有定时任务补偿,通过这样的方式,可以减轻任务调度
        Map<String, Integer> notifyResultMap = executeSettlementNotifyJob(groupBuyTeamEntity.getTeamId());


        return TradePaySettlementEntity.builder()
                .source(tradePaySuccessEntity.getSource())
                .channel(tradePaySuccessEntity.getChannel())
                .userId(tradePaySuccessEntity.getUserId())
                .teamId(apply.getTeamId())
                .activityId(groupBuyTeamEntity.getActivityId())
                .outTradeNo(tradePaySuccessEntity.getOutTradeNo())
                .build();
    }

    @Override
    public Map<String, Integer> executeSettlementNotifyJob() {
        log.info("拼团交易-执行结算通知任务");

        List<NotifyTaskEntity> notifyTaskEntityList = repository.queryUnexecutedNotifyTaskList(null);
        return execSettlementNotifyJob(notifyTaskEntityList);
    }

    private Map<String, Integer> execSettlementNotifyJob(List<NotifyTaskEntity> notifyTaskEntityList) {
        int successCount = 0;
        int errorCount = 0;
        int retryCount = 0;

        for (NotifyTaskEntity notifyTaskEntity : notifyTaskEntityList) {
            String response = tradePort.groupBuyNotify(notifyTaskEntity);
            if (NotifyTaskHTTPEnumVO.SUCCESS.getCode().equals(response)) {
                int updateCount = repository.updateNotifyTaskStatsSuccess(notifyTaskEntity.getTeamId());
                if (1 == updateCount){
                    successCount += 1;
                }

            } else if (NotifyTaskHTTPEnumVO.ERROR.getCode().equals(response)) {
                if (notifyTaskEntity.getNotifyCount() < 5) {
                    int updateCount = repository.updateNotifyTaskStatsError(notifyTaskEntity.getTeamId());
                    if (updateCount == 1){
                        errorCount +=1;
                    }
                } else {
                    int updateCount = repository.updateNotifyTaskStatsRetry(notifyTaskEntity.getTeamId());
                    if (updateCount == 1){
                        retryCount += 1;
                    }
                }
            }
        }

        Map<String,Integer> resultMap =new HashMap<>();
        resultMap.put("waitCount", notifyTaskEntityList.size());
        resultMap.put("successCount",successCount);
        resultMap.put("errorCount",errorCount);
        resultMap.put("retryCount",retryCount);
        return resultMap;
    }

    @Override
    public Map<String, Integer> executeSettlementNotifyJob(String teamId) {
        List<NotifyTaskEntity> notifyTaskEntityList = repository.queryUnexecutedNotifyTaskList(teamId);
        return execSettlementNotifyJob(notifyTaskEntityList);
    }
}
